﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace Heyo.Controls
{
    /// <summary>
    /// FloatingBar.xaml 的交互逻辑
    /// </summary>
    public partial class FloatHint : ContentControl
    {
        public static readonly DependencyProperty TargetElementProperty = DependencyProperty.Register(
            "TargetElement", typeof(FrameworkElement), typeof(FloatHint), new PropertyMetadata(default(FrameworkElement)
            , TargetElementChanged));

        private static void TargetElementChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.OldValue != null)
            {
                ((FrameworkElement)e.OldValue).MouseEnter -= ((FloatHint)d).Target_MouseEnter;
                ((FrameworkElement)e.OldValue).MouseLeave -= ((FloatHint)d).Target_MouseLeave;
            }


            if (e.NewValue == null) return;

            ((FrameworkElement)e.NewValue).MouseEnter += ((FloatHint)d).Target_MouseEnter;
            ((FrameworkElement)e.NewValue).MouseLeave += ((FloatHint)d).Target_MouseLeave;

            //((FloatHint)d).Margin = new Thickness(0, -((FrameworkElement)d).ActualHeight - 8, 0, 0);
        }

        public FrameworkElement TargetElement
        {
            get => (FrameworkElement) GetValue(TargetElementProperty);
            set => SetValue(TargetElementProperty, value);
        }
        public enum Direction
        {
            Top,
            Bottom,
            Left,
            Right
        }

        public UIElement Title
        {
            get => TitleHost.Child;
            set => TitleHost.Child = value;
        }
        public UIElement Hint
        {
            get => ContentHost.Child;
            set => ContentHost.Child=value;
        }
        public FloatHint()
        {
            InitializeComponent();
            MouseEnter += (s, e) => { Show(); };
            Loaded += FloatHint_Loaded;
            
            InitAnimation();

        }

        //private bool dontInit = false;
        //public FloatHint(bool dontInit)
        //{
        //    this.dontInit = dontInit;

        //    InitializeComponent();
        //    MouseEnter += (s, e) => { Show(); };
        //    Loaded += FloatHint_Loaded;
        //    VerticalAlignment = VerticalAlignment.Top;
        //    InitAnimation();
        //}
        //protected override void OnInitialized(EventArgs e)
        //{
        //    base.OnInitialized(e);
        //    if(dontInit) return;

        //    Grid grid = new Grid();
        //    ContentPresenter content = new ContentPresenter
        //    {
        //        Content = Content
        //    };

        //    FloatHint userControl = new FloatHint(true) {Host = {Child = content}};

        //    grid.Children.Add(userControl);
        //    Content = userControl;
        //}
        private void InitAnimation()
        {
            MatrixAnim.RenderTransformOrigin = new Point(0.5, 0.5);
            MatrixAnim.AnimFunction = new PowerEase() { Power = 4, EasingMode = EasingMode.EaseInOut };
            //OpacityAnim.AnimFunction = new PowerEase() { Power = 2, EasingMode = EasingMode.EaseOut };
            OpacityAnim.SpeedRatio = 4;
            MatrixAnim.SpeedRatio = 4;
        }

        private void FloatHint_Loaded(object sender, RoutedEventArgs e)
        {
            //((FrameworkElement)Parent).MouseEnter += Target_MouseEnter;
            //((FrameworkElement)Parent).MouseLeave += FloatHint_MouseLeave;
            VerticalAlignment = VerticalAlignment.Top;
        }

        private void Target_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            Hide();
        }

        private void Target_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            Show();
        }

        public Thickness TipMargin
        {
            get => TopTip.Margin;
            set => TopTip.Margin = BottomTip.Margin = LeftTip.Margin = RightTip.Margin = value;
        }
        private bool _isShow = false;
        public void Show()
        {
            if (_isShow) return;
            _isShow = true;
            PreDirection();
            MatrixAnim.BeginAnimation();
            OpacityAnim.BeginAnimation();
        }
        public void Hide()
        {
            if (!_isShow) return;
            _isShow = false;
            PreDirection();
            MatrixAnim.BeginInverseAnimation();
            OpacityAnim.BeginInverseAnimation();
        }
        private void PreDirection()
        {
            TopTip.Visibility = Visibility.Collapsed;
            BottomTip.Visibility = Visibility.Collapsed;
            LeftTip.Visibility = Visibility.Collapsed;
            RightTip.Visibility = Visibility.Collapsed;

            MatrixAnim.TransTo = new MatrixTransform(1, 0, 0, 1, 0, 0);

            switch (TipDirection)
            {
                default:
                    {
                        MatrixAnim.TransFrom = new MatrixTransform(0.75, 0, 0, 0.75, 0, -Height / 4);
                        if (!ShowTip)
                            break;
                        TopTip.Visibility = Visibility.Visible;
                        break;
                    }
                case Direction.Top:
                    {
                        MatrixAnim.TransFrom = new MatrixTransform(0.75, 0, 0, 0.75, 0, Height / 4);
                        if (!ShowTip)
                            break;
                        BottomTip.Visibility = Visibility.Visible;
                        break;
                    }
                case Direction.Bottom:
                    {
                        MatrixAnim.TransFrom = new MatrixTransform(0.75, 0, 0, 0.75, 0, -Height / 4);
                        if (!ShowTip)
                            break;
                        TopTip.Visibility = Visibility.Visible;
                        break;
                    }
                case Direction.Left:
                    {
                        MatrixAnim.TransFrom = new MatrixTransform(0.75, 0, 0, 0.75, Width / 4, 0);
                        if (!ShowTip)
                            break;
                        RightTip.Visibility = Visibility.Visible;
                        break;
                    }
                case Direction.Right:
                    {
                        MatrixAnim.TransFrom = new MatrixTransform(0.75, 0, 0, 0.75, -Width / 4, 0);

                        if (!ShowTip)
                            break;
                        LeftTip.Visibility = Visibility.Visible;
                        break;
                    }
            }

        }
        public Direction TipDirection { get; set; }
        public bool ShowTip { get; set; } = true;
    }
}
